package cn.edu.seu.herald.informationplatform.util.logger;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Logger {

	private static Map<Object, Logger> _instancePool;
	
	private static final String TYPE_INFO = "信息";
	
	private static final String TYPE_WARNING = "警告";
	
	private static final String TYPE_ERROR = "错误";
	
	private static final String LOG_FORMAT = "%s %s\r\n%s: %s\r\n\r\n";
	
	private String _identifierText;
	
	private PrintStream _out;
	
	public synchronized static Logger getInstance(Object identifier) {
		if (_instancePool == null) {
			_instancePool = new HashMap<Object, Logger>();
		}
		
		if (_instancePool.containsKey(identifier)) {
			return _instancePool.get(identifier);
		}
		
		Logger newLogger = new Logger(identifier.toString());
		_instancePool.put(identifier, newLogger);
		return newLogger;
	}
	
	private static Date getCurrentTime() {
		return new Date();
	}
	
	private static String getFormattedTime(Date date) {
		DateFormat mediumDateFormat = DateFormat.getDateTimeInstance(
				DateFormat.MEDIUM,DateFormat.MEDIUM);
		return mediumDateFormat.format(date);
	}
	
	private static String exceptionToString(Throwable t) {
		StringWriter sWriter = new StringWriter();
		PrintWriter pWriter = new PrintWriter(sWriter);
		t.printStackTrace(pWriter);
		return sWriter.toString();
	}
	
	protected Logger() {
		_identifierText = null;
	}
	
	protected Logger(String identifierText) {
		_identifierText = identifierText;
	}
	
	public void setPrintStream(PrintStream out) {
		_out = out;
	}
	
	public boolean isPrintStreamInitialized() {
		return _out != null;
	}
	
	public void info(String info) {
		print(info, TYPE_INFO);
	}
	
	public void warning(String warning) {
		print(warning, TYPE_WARNING);
	}
	
	public void warning(Throwable t) {
		warning(exceptionToString(t));
	}
	
	public void error(String error) {
		print(error, TYPE_ERROR);
	}
	
	public void error(Throwable t) {
		error(exceptionToString(t));
	}
	
	private void print(String content, String type) {
		if (_out == null) {
			throw new LoggerException("outputstream not initialized");
		}
		
		_out.printf(LOG_FORMAT,
				getFormattedTime(getCurrentTime()),
				_identifierText,
				type,
				content);
	}

}
